/*
 * Copyright (c) 2013.
 * 游戏服务器核心代码编写人陈磊拥有使用权
 * 联系方式：E-mail:13638363871@163.com ;qq:502959937
 * 个人博客主页：http://my.oschina.net/chenleijava
 */

package com.dc.gameserver.serverCore.model.dbsql.modelService;

import com.dc.gameserver.baseConfig.Config;
import com.dc.gameserver.exceptions.dataException;
import com.dc.gameserver.extComponents.utilsKit.mybatisPagination.Page;
import com.dc.gameserver.proto.itemserverprotoVo.bookVO;
import com.dc.gameserver.proto.itemserverprotoVo.equVO;
import com.dc.gameserver.proto.itemserverprotoVo.goodsResponse;
import com.dc.gameserver.proto.itemserverprotoVo.spriteVo;
import com.dc.gameserver.serverCore.model.dbsql.mapper.*;
import com.dc.gameserver.serverCore.model.dbsql.modelCache.ModelCacheService;
import com.dc.gameserver.serverCore.model.dbsql.modelVo.*;
import com.dc.gameserver.serverCore.model.gamemodel.*;
import com.dc.gameserver.serverCore.model.gamemodel.script.ScriptFactory;
import com.dc.gameserver.serverCore.service.battle.GameFormula;
import com.dc.gameserver.serverCore.service.character.PlayerInstance;
import javolution.util.FastTable;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author 石头哥哥
 *         Date: 13-11-26</br>
 *         Time: 下午4:50</br>
 *         Package: com.dc.gameserver.serverCore.model.dbsql.modelService</br>
 *  默认为可读写
 *  事务隔离级别用于处理多事务并发的情况，通常使用数据库的默认隔离级别即可，基本不需要进行设置
 * spring 默认事务传播行为   :REQUIRED
 * 在单独使用不带任何参数的 @Transactional 注释时，传播模式要设置为 REQUIRED，
 * 只读标志设置为 false(即是可读写)，事务隔离级别设置为 READ_COMMITTED，而且事务不会针对受控异常（checked exception）回滚。
 *
 * 数据库操作
 */
@Service
@SuppressWarnings("unchecked")
public class PlayerService {

    private static final Logger LOGGER= LoggerFactory.getLogger(PlayerService.class);

    @Resource
    private TUserMapper tUserMapper;

    @Resource
    private TRoleMapper tRoleMapper;

    //玩家道具信息列表
    @Resource
    private TRoleItemPropsMapper tRoleItemPropsMapper;

    //玩家装备列表
    @Resource
    private TRoleEquMapper tRoleEquMapper;

    //秘籍信息列表
    @Resource
    private TRoleBookMapper tRoleBookMapper;

    //玩家area信息列表
    @Resource
    private TRoleAreaMapper tRoleAreaMapper;

    //玩家关卡信息列表
    @Resource
    private TPointPrograssMapper tPointPrograssMapper;

    @Resource
    private ModelCacheService modelCacheService;

    @Resource
    private SqlSessionTemplate sqlSessionTemplate;

    @Resource
    private TSpriteMapper tSpriteMapper;

    /**
     * 在角色初始化的时候会加载装备到缓存，当数据更新之后
     * 先更新db，然后更新缓存，同时将更新的数据推送给前端
     * 装备加载请求处理
     * @param roleID 角色编号
     * @param type  类型/部位
     * @return
     */
    public FastTable<TRoleEqu> equLoading(int roleID,int type){
        List<TRoleEqu> equList= (List<TRoleEqu>) modelCacheService.findListByPrefixID(ModelCacheService.EQU_PREFIX(roleID));
        if (equList==null)return null;
        FastTable<TRoleEqu> temp =new FastTable<TRoleEqu>();
        for (TRoleEqu equ:equList){
            if (equ.getEqutype()==type){
                temp.addLast(equ);
            }
        }
        if (temp.size()!=0){
            return temp;
        }
        return null;
    }

    /**
     * 在角色初始化的时候会加载秘籍到缓存，当数据更新之后
     * 先更新db，然后更新缓存，同时将更新的数据推送给前端
     * 秘籍加载请求
     * @param roleID 角色编号
     * @param type  类型/部位
     * @return
     */
    public FastTable<TRoleBook> bookLoading(int roleID,int type){
        List<TRoleBook> bookList = (List<TRoleBook>) modelCacheService.findListByPrefixID(ModelCacheService.BOOK_PREFIX(roleID));
        if (bookList==null)return null;
        FastTable<TRoleBook> temp =new FastTable<TRoleBook>();
        for (TRoleBook book:bookList){
            if (book.getBooktype()==type){
                temp.addLast(book);
            }
        }
        if (temp.size()!=0){
            return temp;
        }
        return null;
    }


    /**
     *
     * @param roleID
     * @param type
     * @return
     */
    public FastTable<TSprite> spriteLoading(int roleID,int type){
        List<TSprite> spriteList = (List<TSprite>) modelCacheService.findListByPrefixID(ModelCacheService.SPRITE_PREFIX(roleID));
        if (spriteList==null)return null;
        FastTable<TSprite> temp =new FastTable<TSprite>();
        for (TSprite sprite:spriteList){
            if (sprite.getSpiritetype()==type){
                temp.addLast(sprite);
            }
        }
        if (temp.size()!=0){
            return temp;
        }
        return null;
    }

    /**
     * 道具
     * 在角色初始化的时候会加载道具到缓存，当数据更新之后
     * 先更新db，然后更新缓存，同时将更新的数据推送给前端
     *  道具加载请求
     * @param roleID 角色编号
     * @param type  类型/部位
     * @return
     */
    public FastTable<TRoleItemProps> itemLoading(int roleID,int type){
        List<TRoleItemProps> itemPropsList = (List<TRoleItemProps>) modelCacheService.findListByPrefixID(ModelCacheService.PROPS_PREFIX(roleID));
        if (itemPropsList==null)return null;
        FastTable<TRoleItemProps> temp =new FastTable<TRoleItemProps>();
        for (TRoleItemProps itemProps:itemPropsList){
            if (itemProps.getType()==type){
                temp.addLast(itemProps);
            }
        }
        if (temp.size()!=0){
            return temp;
        }
        return null;
    }

    @Transactional
    public void updateArea(TRoleArea tRoleArea) throws dataException{
        tRoleAreaMapper.updateByPrimaryKey(tRoleArea);
    }

    /**
     * 更新关卡
     * @param prograss
     */
    @Transactional
    public void  updateLevel(TPointPrograss prograss){
        //update level db
        tPointPrograssMapper.updateByPrimaryKey(prograss);
    }


    /**
     *更新神识关卡
     * @param prograss
     */
    @Transactional
    public void insertSoulLevel(TPointPrograss prograss){
        tPointPrograssMapper.insert(prograss);
    }

    /**
     * 开启新的区域 和 关卡
     * @param   roleID     roleID
     * @param areaModel  新区域model
     * @param levelModel 新关卡model
     */
    @Transactional
    public void openNewAreaAndLevel(int roleID,AreaModel areaModel,LevelModel levelModel){
        //刷入区域信息 ,update cache
        TRoleArea tRoleArea=new TRoleArea();
        tRoleArea.setOwnerid(roleID);
        tRoleArea.setRoleareaid(areaModel.getId());
        tRoleArea.setRoleareastatus((byte) 0x1); //area 状态：1:开启;2.未开启;
        //1.未领取(已经达到三星)，2.已领取，3.未达三星
        tRoleArea.setAllstartsreword((byte) 0x3); //没有达到三星
        tRoleAreaMapper.insert(tRoleArea);

        //update cache
        List<TRoleArea>tRoleAreaList=
                (List<TRoleArea>) modelCacheService.
                        findListByPrefixID(ModelCacheService.AREA_PREFIX(roleID));

        tRoleAreaList.add(tRoleArea);
        modelCacheService.addListByPrefixID(ModelCacheService.AREA_PREFIX(roleID),tRoleAreaList);

        //刷入第一个关卡信息 ,update cache
        TPointPrograss pointPrograss=new TPointPrograss();
        pointPrograss.setPointid(levelModel.getId());       //关卡编号
        pointPrograss.setPointstarnum((byte) 0);//关卡星级数量
        pointPrograss.setPointstatus((byte) 1);     //关卡完成状态 1:未完成;2.已完成;
        pointPrograss.setBelongareaid(levelModel.getAreaID()); //关卡所属区域ID
        pointPrograss.setRoleid(roleID); //角色ID
        pointPrograss.setPointtype(levelModel.getLevelType());  //关卡类型 1.普通 2.神识 3.隐藏
        pointPrograss.setPointpercompletenum(0); //每天完成的次数
        pointPrograss.setPointlasttimes(0);   //关卡剩余可完成（可玩+）次数  针对隐藏关卡
        pointPrograss.setFirststartrward(false);
        tPointPrograssMapper.insert(pointPrograss);

        List<TPointPrograss> pointPrograssList= (List<TPointPrograss>) modelCacheService
                .findListByPrefixID(ModelCacheService.POINT_PROGRASS_PREFIX(roleID));
        pointPrograssList.add(pointPrograss);
        modelCacheService.addListByPrefixID(ModelCacheService.POINT_PROGRASS_PREFIX(roleID),pointPrograssList);
    }


    /**
     * 开启新的关卡
     * @param roleID  角色编号
     * @param levelModel 关卡编号
     */
    @Transactional
    public void openLevel(int roleID,LevelModel levelModel){
        //刷入第一个关卡信息 ,update cache
        TPointPrograss pointPrograss=new TPointPrograss();
        pointPrograss.setPointid(levelModel.getId());       //关卡编号
        pointPrograss.setPointstarnum((byte) 0);//关卡星级数量
        pointPrograss.setPointstatus((byte) 1);     //关卡完成状态 1:未完成;2.已完成;
        pointPrograss.setBelongareaid(levelModel.getAreaID()); //关卡所属区域ID
        pointPrograss.setRoleid(roleID); //角色ID
        pointPrograss.setPointtype(levelModel.getLevelType());  //关卡类型 1.普通 2.神识 3.隐藏
        pointPrograss.setPointpercompletenum(0); //每天完成的次数
        pointPrograss.setPointlasttimes(0);   //关卡剩余可完成（可玩+）次数  针对隐藏关卡
        tPointPrograssMapper.insert(pointPrograss); 
        //update cache
        List<TPointPrograss> pointPrograssList= (List<TPointPrograss>) modelCacheService
                .findListByPrefixID(ModelCacheService.POINT_PROGRASS_PREFIX(roleID));
        pointPrograssList.add(pointPrograss);
        modelCacheService.addListByPrefixID(ModelCacheService.POINT_PROGRASS_PREFIX(roleID),pointPrograssList);
    }


    /**
     * 分页查询关卡
     * @param player
     * @return
     */
    public List<TPointPrograss> getPrograssView(PlayerInstance player){
        TPointPrograssExample tPointPrograssExample=new TPointPrograssExample();
        Page page=player.getPage();
        int begin=page.getBegin();
        tPointPrograssExample.setLimitStart(begin);
        tPointPrograssExample.setLimitEnd(page.getEnd());
        page.setBegin(begin+ Config.DEFAULT_VALUE.GAME_VALUE.PrograssPageSize);   // for next  select
       return tPointPrograssMapper.selectByExample(tPointPrograssExample);
    }

    /**
     * 先更新db，然后更新缓存
     * 当玩家登录验证成功后
     * 加载玩家装备 ，秘籍 ，道具
     * 技能 秘籍 装备
     */
    public goodsResponse IntiPlayerInfo(PlayerInstance player,TRole tRole){
        try {
            int roleMaxStateID=tRole.getRolemaxstate();
            int roleID=player.getID();
            //active
            FastTable<ItemCell> itemCells = player.nextItemCell();
            // 推送初始化信息
            goodsResponse.Builder builder=goodsResponse.newBuilder();

            //初始化 装备
            TRoleEquExample tRoleEquExample=new TRoleEquExample();
            TRoleEquExample.Criteria criteria=tRoleEquExample.createCriteria();
            criteria.andOwneridEqualTo(roleID);
            List<TRoleEqu> equList = this.tRoleEquMapper.selectByExample(tRoleEquExample);
            tRoleEquExample.clear();
            tRoleEquExample=null;
            if (equList!=null)modelCacheService.addListByPrefixID(ModelCacheService.EQU_PREFIX(roleID), equList);
            for (TRoleEqu roleEqu:equList){
                byte itemLocation= roleEqu.getEqulocation();
                if (itemLocation!=-1){   //说明在展现面板中
                    equVO.Builder equvo=equVO.newBuilder();
                    equvo.setEquID(roleEqu.getEquid());
                    equvo.setEquTypeID(roleEqu.getEqutypeid());
                    equvo.setEquLevel(roleEqu.getEqulevel());
                    equvo.setEquTimeOut(roleEqu.getEqutimeout());
                    equvo.setEquLocation(roleEqu.getEqulocation());
                    equvo.setEquPinZhi(roleEqu.getEqupinzhi());
                    equvo.setEquPinJie(roleEqu.getEqupinjie());
                    equvo.setEquPinJieExp(roleEqu.getEqupinjieexp());

                    Double effectnum=roleEqu.getEffectnum1();
                    Double effectnumgrowup=roleEqu.getEffectnumgrowup1();
                    if (effectnum!=null) equvo.setEffectNum1(effectnum);
                    if (effectnumgrowup!=null)equvo.setEffectNumGrowUp1(effectnumgrowup);

                    effectnum=roleEqu.getEffectnum2();
                    effectnumgrowup=roleEqu.getEffectnumgrowup2();

                    if (effectnum!=null)equvo.setEffectNum2(effectnum);
                    if (effectnumgrowup!=null)equvo.setEffectNumGrowUp2(effectnumgrowup);

                    effectnum=roleEqu.getEffectnum3();
                    effectnumgrowup=roleEqu.getEffectnumgrowup3();
                    if (effectnum!=null) equvo.setEffectNum3(effectnum);
                    if (effectnumgrowup!=null)equvo.setEffectNumGrowUp3(effectnumgrowup);

                    equvo.setItemType(roleEqu.getItemtype());
                    equvo.setType(roleEqu.getEqutype());
                    builder.addEqu(equvo.build());
                    // 初始化面板
                    for (ItemCell cell:itemCells){
                        if (cell.getItemLocation()==itemLocation){
                            cell.setItemID(roleEqu.getEquid());   //编号
                            cell.setItemTypeID(roleEqu.getEqutypeid()); //类型编号
                            cell.setItemType(roleEqu.getItemtype()); //类型  1 装备 2.秘籍 3.道具
                            break; //跳出当前循环   to next
                        }
                    }
                }
            }


            //初始化灵脉，灵泉， 蒲团  vo
            TSpriteExample spriteExample=new TSpriteExample();
            TSpriteExample.Criteria spriteCriteria=spriteExample.createCriteria();
            spriteCriteria.andOwneridEqualTo(roleID);
            List<TSprite> spriteList=this.tSpriteMapper.selectByExample(spriteExample);
            spriteExample.clear();
            spriteExample=null;
            if (spriteList!=null)modelCacheService.addListByPrefixID(ModelCacheService.SPRITE_PREFIX(roleID), spriteList);      //add to cache
            for (TSprite sprite:spriteList){
                byte itemLocation= sprite.getSpritelocation();
                if (itemLocation!= 0xffffffff){ //已经装备
                    if (sprite.getDestory()== 0x2)continue; //该对象被销毁
                     spriteVo.Builder _spriteVo=spriteVo.newBuilder();
                    _spriteVo.setSpiriteID(sprite.getSpiriteid());
                    _spriteVo.setSpiriteTypeID(sprite.getSpiritetypeid());
                    _spriteVo.setSpiriteItemType(sprite.getItemtype());
                    _spriteVo.setType(sprite.getSpiritetype());
                    _spriteVo.setSpiritePinJie(sprite.getSpiritepinjie());
                    _spriteVo.setSpiritePinZhi(sprite.getSpiritepinzhi());
                    _spriteVo.setSpiriteCurrent(sprite.getSpiritecurrent());
                    _spriteVo.setSpiritelocation(sprite.getSpritelocation());
                    builder.addSpirite(_spriteVo.build());
                    for (ItemCell cell:itemCells){
                        if (cell.getItemLocation()==itemLocation){
                            cell.setItemID(_spriteVo.getSpiriteID());   //编号
                            cell.setItemTypeID(_spriteVo.getSpiriteTypeID()); //类型编号
                            cell.setItemType(_spriteVo.getSpiriteItemType()); //类型    1 装备 2.秘籍 3.道具
                            break; //跳出当前循环
                        }
                    }
                }
            }


            /**开启的灵泉位置**/
            FastTable<Integer> LingQuanLocations= player.openSpriteLocation(tRole.getLingquanlocation());
            if (LingQuanLocations!=null){
                builder.addAllOpenLingQaunlocationID(LingQuanLocations);
                LingQuanLocations.clear();
                LingQuanLocations=null;
            }


            //初始化 秘籍
            TRoleBookExample tRoleBooksExample=new TRoleBookExample();
            TRoleBookExample.Criteria bookCriteria=tRoleBooksExample.createCriteria();
            bookCriteria.andOwneridEqualTo(roleID);
            List<TRoleBook> booksList=this.tRoleBookMapper.selectByExample(tRoleBooksExample);
            tRoleBooksExample.clear();
            tRoleBooksExample=null;
            if (booksList!=null)modelCacheService.addListByPrefixID(ModelCacheService.BOOK_PREFIX(roleID), booksList);
            //获取玩家开启的境界列表，从而获取开启的功法期
            for (TRoleBook roleBook:booksList){
                byte itemLocation= roleBook.getBooklocation();
                if (itemLocation!= 0xffffffff){   //说明在展现面板中
                    bookVO.Builder bookVo=bookVO.newBuilder();
                    bookVo.setBookID(roleBook.getBookid());
                    bookVo.setBookTypeID(roleBook.getBooktypeid());
                    bookVo.setBookSuccessUseTimes(roleBook.getBooksuccessusetimes());
                    bookVo.setBookTimeOut(roleBook.getBooktimeout());
                    bookVo.setBookLocation(roleBook.getBooklocation());
                    bookVo.setBookPinZhi(roleBook.getBookpinzhi());
                    bookVo.setBookPinJie(roleBook.getBookpinjie());
                    bookVo.setBookPinJieExp(roleBook.getBookpinjieexp());
                    bookVo.setItemType(roleBook.getItemtype());
                    bookVo.setType(roleBook.getBooktype());
                    builder.addBook(bookVo.build());
                    // 初始化面板 ，功法书 ,技能书 ，神识书
                    for (ItemCell cell:itemCells){
                        if (cell.getItemLocation()==itemLocation){
                            cell.setItemID(roleBook.getBookid());   //编号
                            cell.setItemTypeID(roleBook.getBooktypeid()); //类型编号
                            cell.setItemType(roleBook.getItemtype()); //类型    1 装备 2.秘籍 3.道具
                            break; //跳出当前循环
                        }
                    }
                }
            }


            //处理功法书初始化
            FastTable<ItemCell> GongList=player.getGongItem();
            FastTable<Integer>  stateIDList=player.OpenGongByStateID(roleMaxStateID);
            int GongSize=0,stateIDSize=0;
            GongSize=GongList.size();
            stateIDSize=stateIDList.size();
            if (GongSize!=0&&stateIDSize!=0&&GongSize==stateIDSize){
                for (ItemCell cell:GongList){
                    cell.setStateID(stateIDList.getFirst());  //the first is the 1 ----10
                }
            }

//            // 返回相应开启的功法编号位置
//            builder.addAllOpenGonglocationID(stateIDList);

            GongList.clear();
            GongList=null;
            stateIDList.clear();
            stateIDList=null;



            //初始化道具 （消耗品）
            TRoleItemPropsExample tRoleItemPropsExample=new TRoleItemPropsExample();
            TRoleItemPropsExample.Criteria criteriatRoleItemPropsExample=tRoleItemPropsExample.createCriteria();
            criteriatRoleItemPropsExample.andOwneridEqualTo(roleID);
            List<TRoleItemProps> propsList = this.tRoleItemPropsMapper.selectByExample(tRoleItemPropsExample);
            tRoleItemPropsExample.clear();
            tRoleItemPropsExample=null;
            criteriatRoleItemPropsExample=null;
            if (propsList !=null)modelCacheService.addListByPrefixID(ModelCacheService.PROPS_PREFIX(roleID), propsList);


            //初始化 玩家areas
            TRoleAreaExample tRoleAreaExample=new TRoleAreaExample();
            TRoleAreaExample.Criteria criteriatRoleAreaExample=tRoleAreaExample.createCriteria();
            criteriatRoleAreaExample.andOwneridEqualTo(roleID);
            List<TRoleArea> areasList = this.tRoleAreaMapper.selectByExample(tRoleAreaExample);
            tRoleAreaExample.clear();
            tRoleAreaExample=null;
            criteriatRoleAreaExample=null;
            if (areasList !=null)modelCacheService.addListByPrefixID(ModelCacheService.AREA_PREFIX(roleID), areasList);


            //关卡进度记录数据
            TPointPrograssExample tPointPrograssExample=new TPointPrograssExample();
            TPointPrograssExample.Criteria criteriatPointPrograssExample=tPointPrograssExample.createCriteria();
            criteriatPointPrograssExample.andRoleidEqualTo(roleID);
            List<TPointPrograss> pointsList = this.tPointPrograssMapper.selectByExample(tPointPrograssExample);
//            int size= pointsList.size();
            if (pointsList !=null)modelCacheService.addListByPrefixID(ModelCacheService.POINT_PROGRASS_PREFIX(roleID), pointsList);
//            if (size!=0){
//                /**分页处理*/
//                Page page=player.getPage();
//                page.setCount(pointsList.size());
//            }
            tPointPrograssExample.clear();
            tPointPrograssExample=null;
            criteriatPointPrograssExample=null;

            return builder.build();
        }catch (Exception e){
            throw new dataException(e);
        }
    }

    /**
     * 根据用户名查询user  ,并作相应的验证
     * @param userAccount   userAccount
     * @return
     * slave select
     */
    public TUser getUserByAccount(String userAccount,String pwd) throws dataException {
        TUser user=null;
        TUserExample tUserExample=new TUserExample();
        TUserExample.Criteria criteria= tUserExample.createCriteria();
        criteria.andUseracountEqualTo(userAccount);
        criteria.andUserpwdEqualTo(pwd);
        List<TUser> userList= tUserMapper.selectByExample(tUserExample);
        tUserExample.clear();
        tUserExample=null;
        criteria=null;
        if (userList.size()>0){
            user= userList.get(0);
            userList.clear();
            userList=null;
        }
        return user;
    }

    /**
     *
     * @param userID
     * @return
     */
    public TRole getRoleByUserID(int userID){
        TRole  tRole=null;
        TRoleExample tRoleExample=new TRoleExample();
        TRoleExample.Criteria criteria=tRoleExample.createCriteria();
        criteria.andUseridEqualTo(userID);//单服对应一个帐号
        List<TRole> roleList=tRoleMapper.selectByExample(tRoleExample);
        tRoleExample.clear();
        tRoleExample=null;
        criteria=null;
        if (roleList.size()>0){
            tRole=roleList.get(0);
            roleList.clear();
            roleList=null;
        }
        return  tRole;
    }


    /**
     * 检查用户角色名称是否存在
     * @param roleName
     * @return
     * slave    非事务性的查询
     */
    public TRole  checkRole(String roleName){
        TRole tRole=null;
        FastTable<String> roleNameList= (FastTable<String>) modelCacheService.findList(Config.DEFAULT_VALUE.SERVER_VALUE.gameserverPort);
        if (roleNameList!=null){
            for (String name:roleNameList){
                if (name.equalsIgnoreCase(roleName)){
                    tRole=new TRole();
                    tRole.setRolename(roleName);
                }
            }
        }
        return  tRole;
    }


    /**
     * cache name  before game server running
     * key is  gameServerPort
     */
    public void IntiRoleNameIntoCache(){
        TRoleExample tRoleExample=new TRoleExample();
        List<TRole> roleList=tRoleMapper.selectByExample(tRoleExample);
        FastTable<String> roleNameList=new FastTable<String>();
        for (TRole role:roleList){
            roleNameList.add(role.getRolename());  //角色名称
        }
        modelCacheService.addList(Config.DEFAULT_VALUE.SERVER_VALUE.gameserverPort,roleNameList);
    }


    /**
     * 创建角色  刷入基础属性  area
     * 事务性查询，将会被发送到master数据库
     *
     * @param role
     * @return
     */
    @Transactional
    public  void creatRole(TRole role){
        try {

            /**
             * 刷入角色基础属性值
             */
            BaseRoleModel baseRoleModel= ScriptFactory.baseRoleModel[0];
            for(Map.Entry<Integer,StateModel>entry:ScriptFactory.stateModelFastMap.entrySet()){
                StateModel stateModel=entry.getValue();//默认开启大境界1中的第一个小境界
                /**通过境界变更
                 * blood
                 * sheild
                 * magic
                 * attack
                 * Defence
                 * soual   神识判定
                 * recoveryMagic
                 * ****/
                int blood = GameFormula.Blood(stateModel.getBlood(), 0, 0, 0, 0);
                int magic=GameFormula.Magic(stateModel.getMagic(), 0, 0, 0, 0);
                int recoveryMagic= GameFormula.recoveryMagicForPreRound(stateModel.getRolerecoverymagic(),0,0);
                int sheild=GameFormula.Sheild(stateModel.getSheild(), 0, 0, 0, 0);
                int attack=GameFormula.Attack(stateModel.getAttack(), 0, 0, 0, 0);
                int defence=GameFormula.Defence(stateModel.getDefence(), 0, 0, 0, 0);
                int soul=stateModel.getSoul();
                int maxSoul=GameFormula.MaxSoual(soul, 0, 0, 0, 0); //神识上限


                /*****/
                role.setRolemaxblood(blood);
                role.setRolemaxmagic(magic);
                role.setRolerecoverymagic(recoveryMagic); //法力值恢复
                role.setRolemaxshiled(sheild);
                role.setRoleattack(attack);
                role.setRoledefence(defence);
                role.setRolesual(stateModel.getSoul());
                role.setRolemaxsual(maxSoul); //神识上限值
                role.setRolesualrecovery(stateModel.getRoleSualRecovery());


                role.setRolesmalstate(stateModel.getSmallStateID()); //小境界编号
                role.setRolemaxstate(stateModel.getBigStateID());  //大境界编号


                role.setRolebaseminmomentum(stateModel.getBaseminMomentum()); //基础气势值上限
                role.setRolebasemaxmomentum(stateModel.getBasemaxMomentum()); // 基础气势值下限

                role.setStateid(stateModel.getId());  //境界唯一区分编号   Stateid
                break;
            }

            Date date=new Date();
            long time= date.getTime();
            role.setRoleage(time); //role age
            role.setRolecreattime(date);
            role.setRolestateexperies(0);
            role.setRoleexperiences(baseRoleModel.getRoleExperiences());
            role.setRolelevel(baseRoleModel.getRoleLevel());
            role.setRolemurder(baseRoleModel.getRoleMurder());
            role.setRolemurderlevel(baseRoleModel.getRoleMurderLevel());
            role.setRoleluck(baseRoleModel.getRoleLuck());
            role.setRolelingshinum(baseRoleModel.getRoleLingshiNum());
            role.setRolexianyunum(baseRoleModel.getRoleXianYuNum());
            role.setRolefivetype((byte) 0);//创建角色默认没有五行属性
            long currentTime= System.currentTimeMillis();
            role.setSoultime(currentTime);    //设置神识计时时间戳
            role.setLiqitime(0L);//设置灵气计时时间戳

            role.setLingquanlocation((byte)0x0);
            role.setStorelingqi(0x0);
            role.setStorelingqilimit(0);
            tRoleMapper.insert(role);
            int  roleID=role.getRoleid();

            //刷入area数据，基础属性         默认开启关卡，地图区域
            TRoleArea tRoleArea=new TRoleArea();
            AreaModel areaModel=null;
            for (Map.Entry<Integer,AreaModel> entry:ScriptFactory.areaModelFastMap.entrySet()){
                areaModel=entry.getValue();
                tRoleArea.setOwnerid(roleID);
                tRoleArea.setRoleareaid(areaModel.getId());//区域配置文件编号
                tRoleArea.setRoleareastatus((byte)0x1); //area 状态：1:开启;2.未开启;
                //1.未领取(已经达到三星)，2.已领取，3.未达三星
                tRoleArea.setAllstartsreword((byte) 0x3);
                tRoleAreaMapper.insert(tRoleArea);
                break;
            }

            TRoleAreaExample tRoleAreaExample=new TRoleAreaExample();
            TRoleAreaExample.Criteria criteria=tRoleAreaExample.createCriteria();
            criteria.andOwneridEqualTo(roleID);
            //area cache
            List<TRoleArea>tRoleAreaList=tRoleAreaMapper.selectByExample(tRoleAreaExample);
            if (tRoleAreaList!=null&&tRoleAreaList.size()!=0){
                modelCacheService.addListByPrefixID(ModelCacheService.AREA_PREFIX(roleID),tRoleAreaList);
            }

            //刷入第一个区域对应的第一个主线关卡信息
            TPointPrograss pointPrograss=new TPointPrograss();
            FastTable<LevelModel> levelModels=ScriptFactory.mainLevelFastMap.get(areaModel.getId());
            LevelModel pointModel=levelModels.getFirst();
            pointPrograss.setPointid(pointModel.getId());       //关卡编号
            pointPrograss.setPointstarnum((byte) 0);//关卡星级数量
            pointPrograss.setPointstatus((byte) 0x1);     //关卡完成状态 1:未完成;2.已完成;
            pointPrograss.setBelongareaid(pointModel.getAreaID()); //关卡所属区域ID
            pointPrograss.setRoleid(roleID); //角色ID
            pointPrograss.setPointtype(pointModel.getLevelType());  //关卡类型 1.普通 2.神识 3.隐藏
            pointPrograss.setPointpercompletenum(0); //每天完成的次数
            pointPrograss.setPointlasttimes(0);   //关卡剩余可完成（可玩+）次数  针对隐藏关卡
            pointPrograss.setFirststartrward(false);
            tPointPrograssMapper.insert(pointPrograss);

            //刷入该地区的神识关卡
//            int roleMaxSoul=role.getRolemaxsual();
//            for (LevelModel soulLevel:ScriptFactory.soulLevelList){
//                if (roleMaxSoul>=soulLevel.getSoulNeed()){  //开启神识关卡
//                    pointPrograss.setId(null);
//                    pointPrograss.setPointid(soulLevel.getId());       //关卡编号
//                    pointPrograss.setPointstarnum((byte) 0);//关卡星级数量
//                    pointPrograss.setPointstatus((byte) 0x1);     //关卡完成状态 1:未完成;2.已完成;
//                    pointPrograss.setBelongareaid(soulLevel.getAreaID()); //关卡所属区域ID
//                    pointPrograss.setRoleid(roleID); //角色ID
//                    pointPrograss.setPointtype(soulLevel.getLevelType());  //关卡类型 1.普通 2.神识 3.隐藏
//                    pointPrograss.setPointpercompletenum(0); //每天完成的次数
//                    pointPrograss.setPointlasttimes(0);   //关卡剩余可完成（可玩+）次数  针对隐藏关卡
//                    pointPrograss.setFirststartrward(false);
//                    tPointPrograssMapper.insert(pointPrograss);
//                }
//            }
//            pointPrograss=null;

            //关卡cache
            TPointPrograssExample pointPrograssExample=new TPointPrograssExample();
            TPointPrograssExample.Criteria criteriaPointPrograssExample=pointPrograssExample.createCriteria();
            criteriaPointPrograssExample.andRoleidEqualTo(roleID);
            List<TPointPrograss> prograssList=tPointPrograssMapper.selectByExample(pointPrograssExample);
            pointPrograssExample.clear();
            pointPrograssExample=null;
            criteriaPointPrograssExample=null;
            if (prograssList!=null&&prograssList.size()!=0)
                modelCacheService.addListByPrefixID(ModelCacheService.POINT_PROGRASS_PREFIX(roleID),prograssList);






            List<TRoleBook> bookList= (List<TRoleBook>) modelCacheService.findListByPrefixID(ModelCacheService.BOOK_PREFIX(roleID));
            if (bookList==null){
                bookList=new ArrayList<TRoleBook>();
            }

//            /**
//             *  刷入 技能书
//             */
//            for (Map.Entry<Integer,BookModel>entry:ScriptFactory.bookModelFastMap.entrySet()){
//                BookModel bookModel=entry.getValue();
//                if (bookModel.getType()== 0x1){//部位类型
//                    TRoleBook roleBook=new TRoleBook();
//                    roleBook.setBooktypeid(bookModel.getId());
//                    roleBook.setItemtype(bookModel.getItemType());
//                    roleBook.setOwnerid(roleID);
//                    roleBook.setBookpinzhi(bookModel.getQuality().byteValue());
//                    roleBook.setBookpinjie(bookModel.getSubQuality().byteValue());
//                    roleBook.setBooklevel(1);
//                    roleBook.setBooktype(bookModel.getType().byteValue());
//                    roleBook.setBooklocation((byte)-1);
//                    roleBook.setBooktimeout((long)0);
//                    roleBook.setBookprice(bookModel.getPrice());
//                    roleBook.setBookshowbag(bookModel.getShowInBag());
//                    roleBook.setBookpinjieexp(bookModel.getSuplySubQualityExp());
//                    roleBook.setBooksuccessusetimes(0);
//                    tRoleBookMapper.insert(roleBook);
//                    bookList.add(roleBook);
//                    break;
//                }
//            }
//
//            /**
//             *  刷入 功法书
//             */
//            for (Map.Entry<Integer,BookModel>entry:ScriptFactory.bookModelFastMap.entrySet()){
//                BookModel bookModel=entry.getValue();
//                if (bookModel.getType()== 0x3){   //部位，类型
//                    TRoleBook roleBook=new TRoleBook();
//                    roleBook.setBooktypeid(bookModel.getId());
//                    roleBook.setItemtype(bookModel.getItemType());
//                    roleBook.setOwnerid(roleID);
//                    roleBook.setBookpinzhi(bookModel.getQuality().byteValue());
//                    roleBook.setBookpinjie(bookModel.getSubQuality().byteValue());
//                    roleBook.setBooklevel(1);
//                    roleBook.setBooktype(bookModel.getType().byteValue());
//                    roleBook.setBooklocation((byte)-1);
//                    roleBook.setBooktimeout((long)0);
//                    roleBook.setBookprice(bookModel.getPrice());
//                    roleBook.setBookshowbag(bookModel.getShowInBag());
//                    roleBook.setBookpinjieexp(bookModel.getSuplySubQualityExp());
//                    roleBook.setBooksuccessusetimes(0);
//                    tRoleBookMapper.insert(roleBook);
//                    bookList.add(roleBook);
//                    break;
//                }
//            }


            instertBook(1,roleID,bookList);
            instertBook(2,roleID,bookList);
            instertBook(3,roleID,bookList);

            List<TRoleEqu> equList= (List<TRoleEqu>) modelCacheService.findListByPrefixID(ModelCacheService.EQU_PREFIX(roleID));
            if (equList==null){
                equList=new ArrayList<TRoleEqu>();
            }
            insterEqu(roleID,equList);
            modelCacheService.addListByPrefixID(ModelCacheService.EQU_PREFIX(roleID),equList);

            /***
             *  刷入蒲团 灵脉
             */
            List<TSprite> spriteList= (List<TSprite>) modelCacheService.findListByPrefixID(ModelCacheService.SPRITE_PREFIX(roleID));
            if (spriteList==null){
                spriteList=new ArrayList<TSprite>();
            }
            instertSprite(roleID,spriteList);
            modelCacheService.addListByPrefixID(ModelCacheService.SPRITE_PREFIX(roleID),spriteList);




            //cache book
            modelCacheService.addListByPrefixID(ModelCacheService.BOOK_PREFIX(roleID),bookList);
            //cache role
            modelCacheService.addObjectPrefixID(ModelCacheService.ROLE_PREFIX(roleID), role);
            tRoleAreaExample.clear();
            tRoleAreaExample=null;
            criteria=null;
            tRoleArea=null;
        } catch (Exception e){
            throw  new dataException("创建角色异常",e);
        }

    }


    /**
     * 开启神识关卡
     */
    @Transactional
    @Deprecated
    public FastTable<TPointPrograss> openSoulLevel(TRole tRole){
        int roleMaxSoul=tRole.getRolemaxsual();
        int roleID=tRole.getRoleid();
        String level_prefix=ModelCacheService.POINT_PROGRASS_PREFIX(roleID);
        List<TPointPrograss> cacheLevelList= (List<TPointPrograss>) modelCacheService.findListByPrefixID(level_prefix);
        FastTable<TPointPrograss> willSendList=new FastTable<TPointPrograss>();
        for (LevelModel soulLevel:ScriptFactory.soulLevelList){
            int levelID=soulLevel.getId();
            if (roleMaxSoul>=soulLevel.getSoulNeed()&&!existLevel(levelID,cacheLevelList)){  //开启神识关卡
                TPointPrograss pointPrograss=new TPointPrograss();
                pointPrograss.setPointid(levelID);       //关卡编号
                pointPrograss.setPointstarnum((byte) 0);//关卡星级数量
                pointPrograss.setPointstatus((byte) 0x1);     //关卡完成状态 1:未完成;2.已完成;
                pointPrograss.setBelongareaid(soulLevel.getAreaID()); //关卡所属区域ID
                pointPrograss.setRoleid(roleID); //角色ID
                pointPrograss.setPointtype(soulLevel.getLevelType());  //关卡类型 1.普通 2.神识 3.隐藏
                pointPrograss.setPointpercompletenum(0); //每天完成的次数
                pointPrograss.setPointlasttimes(0);   //关卡剩余可完成（可玩+）次数  针对隐藏关卡
                pointPrograss.setFirststartrward(false);
                //update and cache
                tPointPrograssMapper.insert(pointPrograss);
                cacheLevelList.add(pointPrograss);
                willSendList.addLast(pointPrograss);
            }
        }
        modelCacheService.addListByPrefixID(level_prefix,cacheLevelList);
        return willSendList;
    }


    /**
     * 检查是否已经开启神识该关卡
     * @param levelID
     * @param cacheLevelList
     * @return
     */
    private boolean existLevel(int levelID,List<TPointPrograss> cacheLevelList){
        boolean have=false;
        for (TPointPrograss prograss:cacheLevelList){
             if (prograss.getPointid()==levelID){ //如果存在就返回
                 have=true;
                 return have;
             }
        }
        return have;
    }



    /**
     * 测试工具
     * 刷入精舍信息
     */
    @Deprecated
    public  void instertSprite(int roleID, List<TSprite> spriteList){
        for (Map.Entry<Integer,SpriteModel>entry:ScriptFactory.spriteModelFastMap.entrySet()){
            SpriteModel spriteModel=entry.getValue();
            TSprite sprite=new TSprite();
            sprite.setSpiritetypeid(spriteModel.getId());
            sprite.setOwnerid(roleID);
            sprite.setSpiritepinjie(spriteModel.getSubQuality());
            sprite.setSpiritepinzhi(spriteModel.getQuality());
            sprite.setSpiritetype(spriteModel.getType());
            sprite.setSpiritecurrent(spriteModel.getSpirutMaxlimit());
            sprite.setSpritelocation((byte) 0xffffffff);
            sprite.setItemtype(spriteModel.getItemType());
            sprite.setDestory((byte) 0x1); //未被销毁
            sprite.setSpiritperminutecreat(spriteModel.getSpiritPerMinuteCreat());
            this.tSpriteMapper.insert(sprite);
            spriteList.add(sprite);
        }
    }

    /**
     * 测试工具
     * 刷入指定的秘籍类型
     * @param type 类型 部位
     */
    @Deprecated
    public  void instertBook(int type,int roleID,List<TRoleBook> bookList){
        /**
         *  刷入 功法书
         */
        for (Map.Entry<Integer,BookModel>entry:ScriptFactory.bookModelFastMap.entrySet()){
            BookModel bookModel=entry.getValue();
            if (bookModel.getType()== type){   //部位，类型
                TRoleBook roleBook=new TRoleBook();
                roleBook.setBooktypeid(bookModel.getId());
                roleBook.setItemtype(bookModel.getItemType());
                roleBook.setOwnerid(roleID);
                roleBook.setBookpinzhi(bookModel.getQuality().byteValue());
                roleBook.setBookpinjie(bookModel.getSubQuality().byteValue());
                roleBook.setBooklevel(1);
                roleBook.setBooktype(bookModel.getType().byteValue());
                roleBook.setBooklocation((byte)-1);
                roleBook.setBooktimeout((long)0);
                roleBook.setBookprice(bookModel.getPrice());
                roleBook.setBookshowbag(bookModel.getShowInBag());
                roleBook.setBookpinjieexp(bookModel.getSuplySubQualityExp());
                roleBook.setBooksuccessusetimes(0);
                tRoleBookMapper.insert(roleBook);
                bookList.add(roleBook);
            }
        }

    }


    /**
     * 测试工具
     * 刷入指定的装备类型
     */
    @Deprecated
   public void insterEqu(int roleID,List<TRoleEqu> equList ){
       for (Map.Entry<Integer,EquipmentModel>entry:ScriptFactory.equipmentModelFastMap.entrySet()){
           EquipmentModel equipmentModel=entry.getValue();
           //记录到玩家的物品数据表中
           TRoleEqu roleEqu=new TRoleEqu();
           roleEqu.setOwnerid(roleID);  //装备所属对象
           roleEqu.setEqutypeid(equipmentModel.getId());   //物品编号
           roleEqu.setEqutype(equipmentModel.getType().byteValue());   //部位、类型
           roleEqu.setEqupinzhi(equipmentModel.getQuality().byteValue());   //品质
           roleEqu.setEqupinjie(equipmentModel.getSubQuality().byteValue());  //品阶
           roleEqu.setEqulevel(1);//强化等级
           roleEqu.setEquprice(equipmentModel.getPrice());  //装备售价
           roleEqu.setEqutimeout((long) 0);    //time out
           roleEqu.setEqushowbag(equipmentModel.getShowInBag());  //show bag
           roleEqu.setEqulocation((byte) -1);     //装备位置
           roleEqu.setEqupinjieexp(0);
           roleEqu.setItemtype(equipmentModel.getItemType());  //装备类型 1
           roleEqu.setEffectnum1(equipmentModel.getEffectNum1());
           roleEqu.setEffectnumgrowup1(equipmentModel.getEffectNumGrowUp1());
           roleEqu.setEffectnum2(equipmentModel.getEffectNum2());
           roleEqu.setEffectnumgrowup2(equipmentModel.getEffectNumGrowUp2());
           roleEqu.setEffectnum3(equipmentModel.getEffectNum3());
           roleEqu.setEffectnumgrowup3(equipmentModel.getEffectNumGrowUp3());
           //更新DB  缓存
           tRoleEquMapper.insert(roleEqu);  //
           equList.add(roleEqu);
       }

   }


    /**
     * 更新灵泉属性
     * @param sprite
     * @return  boolean
     */
    @Transactional
    public boolean updateSprite(TSprite sprite) throws dataException{
        boolean status =false;
        try {
            tSpriteMapper.updateByPrimaryKeySelective(sprite);
            status=true;
        }catch (dataException d){
            status =false;
        }
        return status;
    }


    /**
     * 批量更新灵泉属性
     * @param sprites
     * @return  boolean
     */
    @Transactional
    public void updateSpriteBatch(FastTable<TSprite> sprites) throws dataException{
        SqlSession sqlSession=sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
        TSpriteMapper spriteMapper=sqlSession.getMapper(TSpriteMapper.class);
        for (TSprite tSprite:sprites){
            spriteMapper.updateByPrimaryKeySelective(tSprite);
        }
        sqlSession.commit();    //提交事务
        sqlSession.clearCache();
        sqlSession.close();
    }


    /**
     * 更新角色属性
     * @param tRole
     * @return  boolean
     */
    @Transactional
    public boolean updateRole(TRole tRole) throws dataException{
        boolean status =false;
        try {
            tRoleMapper.updateByPrimaryKeySelective(tRole);
            status=true;
        }catch (dataException d){
            status =false;
        }
        return status;
    }


    /**
     * 保存数据 ，清理缓存资源
     * @param roleID 角色ID
     *
     */
    @Transactional
    @SuppressWarnings("unchecked")
    public void saveDbAndClearCache(int roleID){
        SqlSession sqlSession=null;
        try {
            sqlSession=sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);

            //玩家角色信息更新
            TRole tRole= (TRole) modelCacheService.findByPrefixID(ModelCacheService.ROLE_PREFIX(roleID));
            if (tRole!=null){
                TRoleMapper roleMapper=sqlSession.getMapper(TRoleMapper.class);
                roleMapper.updateByPrimaryKeySelective(tRole);
                sqlSession.commit();
                sqlSession.clearCache();
            } else {
                throw new dataException("tRole is null ,please check  cache key");
            }
            modelCacheService.deleteByPrefixID(ModelCacheService.ROLE_PREFIX(roleID));


            //玩家道具信息列表 更新
            List<TRoleItemProps> propsFastTable= (List<TRoleItemProps>) modelCacheService.findListByPrefixID(ModelCacheService.PROPS_PREFIX(roleID));
            if (propsFastTable!=null){
                TRoleItemPropsMapper propsMapper=sqlSession.getMapper(TRoleItemPropsMapper.class);
                for (TRoleItemProps prop:propsFastTable){
                    propsMapper.updateByPrimaryKeySelective(prop);
                }
                sqlSession.commit();
                sqlSession.clearCache();
            }
            modelCacheService.deleteByPrefixID(ModelCacheService.PROPS_PREFIX(roleID));


            //玩家area信息列表 更新
            List<TRoleArea> areasList= (List<TRoleArea>) modelCacheService.findListByPrefixID(ModelCacheService.AREA_PREFIX(roleID));
            if (areasList!=null){
                TRoleAreaMapper areaMapper=sqlSession.getMapper(TRoleAreaMapper.class);
                for (TRoleArea area:areasList){
                    areaMapper.updateByPrimaryKeySelective(area);
                }
                sqlSession.commit();
                sqlSession.clearCache();
            }
            modelCacheService.deleteByPrefixID(ModelCacheService.AREA_PREFIX(roleID));

            //玩家装备信息列表 更新
            List<TRoleEqu> equList= (List<TRoleEqu>) modelCacheService.findListByPrefixID(ModelCacheService.EQU_PREFIX(roleID));
            if (equList!=null){
                TRoleEquMapper roleEquMapper=sqlSession.getMapper(TRoleEquMapper.class);
                for (TRoleEqu roleEqu:equList){
                    roleEquMapper.updateByPrimaryKeySelective(roleEqu);
                }
                sqlSession.commit();
                sqlSession.clearCache();
            }
            modelCacheService.deleteByPrefixID(ModelCacheService.EQU_PREFIX(roleID));


            //玩家秘籍信息列表 更新
            List<TRoleBook> booksList= (List<TRoleBook>) modelCacheService.findListByPrefixID(ModelCacheService.BOOK_PREFIX(roleID));
            if (booksList!=null){
                TRoleBookMapper roleBooksMapper=sqlSession.getMapper(TRoleBookMapper.class);
                for (TRoleBook roleBook:booksList){
                    roleBooksMapper.updateByPrimaryKeySelective(roleBook);
                }
                sqlSession.commit();
                sqlSession.clearCache();
            }
            modelCacheService.deleteByPrefixID(ModelCacheService.BOOK_PREFIX(roleID));


            //玩家关卡信息列表更新
            List<TPointPrograss> pointsList= (List<TPointPrograss>) modelCacheService.findListByPrefixID(ModelCacheService.POINT_PROGRASS_PREFIX(roleID));
            if (pointsList!=null){
                TPointPrograssMapper pointPrograssMapper=sqlSession.getMapper(TPointPrograssMapper.class);
                for (TPointPrograss pointPrograss:pointsList){
                    pointPrograssMapper.updateByPrimaryKeySelective(pointPrograss);
                }
                sqlSession.commit();
                sqlSession.clearCache();
            }
            modelCacheService.deleteByPrefixID(ModelCacheService.POINT_PROGRASS_PREFIX(roleID));

        } catch (dataException e){
                sqlSession.rollback();    //出现异常，事务回滚
        } finally {
               sqlSession.close();
        }
    }

}
